/*
 * Copyright (c) 2018 Nanjing Wind Information Co., Ltd. All Rights Reserved;
 * @Package cn.com.wind.bussiness.util
 * @version 1.0.0
 * @Date 2018年8月2日
 * @author jlren@wind.com.cn
 */
package wind.autotest.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;



/**
 * @Description: <字符串操作类，继承lang3包，若需要复写或新增请在此类>
 * @author jlren@wind.com.cn
 * @Date 2018年8月2日 下午2:35:31
 * 
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils {
	public final static Logger LOGGER = LoggerFactory.getLogger(StringUtils.class);
    private static final Pattern PATTERN_NUMBER = Pattern.compile("\\d+");
    // 区号-直播号码-分机号|直播号码-分机号|手机号|直播号码
    private static final Pattern PATTERN_TLENUMBERS = Pattern.compile(
    		"([\\d]{3,4}\\-[2-9][0-9]{6,7}\\-[0-9]{1,4})|"
    		+"([\\d]{3,4}\\-[2-9][0-9]{6,7})|"
    		+ "([2-9][0-9]{6,7}\\-[0-9]{1,4})|"
    		+ "(1[\\d]{10})|"
    		+ "([2-9][0-9]{6,7})");
    private static final Pattern PATTERN_CHINESE = Pattern.compile("[\\u4e00-\\u9fa5]");
    private static final Pattern PATTERN_ENGLISH = Pattern.compile("[a-zA-Z]+");
	/**
	 * 抽取数字
	 * 
	 * @param str
	 * @return
	 */
	public static String getAllNumber(String str) {
		Matcher m = PATTERN_NUMBER.matcher(str);
		if (m.find()) {
			return m.group(0);
		}
		return "";
	}
	
	/**
	 * 判断是否包含数字
	 * @param str
	 * @return
	 */
	 public static boolean isContainNumber(String str) {
		 if (StringUtils.isEmpty(str)) {
			 return false;
		 }
         Pattern p = Pattern.compile("[0-9]");
         Matcher m = p.matcher(str);
         if (m.find()) {
             return true;
         }
         return false;
     }
	
	/**
     * 全角转半角
     * @param input
     * @return
     */
	public static String toDBC(String input) {
		if (StringUtils.isEmpty(input)) {
			return input;
		}
        char c[] = input.toCharArray();
        for (int i = 0; i < c.length; i++) {
          if (c[i] == '\u3000') {
            c[i] = ' ';
          } else if (c[i] > '\uFF00' && c[i] < '\uFF5F') {
            c[i] = (char) (c[i] - 65248);
          }
        }
        String returnString = new String(c);
        return returnString;
	}
	
	/**
	 * 
	 * 功能描述:<stream 2 string>
	 * @param in
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static String InputStream2String(InputStream in) {
	    InputStreamReader reader = null;
	    try {
	        reader = new InputStreamReader(in, "UTF-8");
	    } catch (UnsupportedEncodingException e1) {
	        e1.printStackTrace();
	    }
	    BufferedReader br = new BufferedReader(reader);
	    StringBuilder sb = new StringBuilder();
	    String line = "";
	    try {
	        while ((line = br.readLine()) != null) {
	            sb.append(line);
	        }
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	    return sb.toString();
	}
	
	/**
	 * 
	 * 功能描述:<检查字符串是否符合正则>
	 * @param text
	 * @param regExpression
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static boolean checkStrByRegular(String text, String regExpression) {		
		if (isEmpty(text) || isEmpty(regExpression)) {
			return false;
		}
		Pattern p = Pattern.compile(regExpression);
		Matcher m = p.matcher(text);

		if (m.find()) {
			return true;
		}
		return false;
	}
	
	/**
	 * 
	 * 功能描述:<判断是否为数字>
	 * @param text
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static boolean isNumbericStr(String text) {		
		return checkStrByRegular(text,"^[\\d\\.]+$");
	}
	
	/**
	 * @param text
	 * @param regExpression
	 * @param groupId
	 * @return	即使匹配不了，返回为空字符串
	 */
	public static String getStrByRegular(String text, String regExpression, int groupId) {
		
		if (StringUtils.isEmpty(regExpression) || StringUtils.isEmpty(text)) {
			return text;
		}

		Pattern p = Pattern.compile(regExpression);
		
		
		Matcher m = p.matcher(text);
		
		if (m.find()) {
			return m.group(groupId);
		}

		return "";
	}
	
	
	
	/**
	 * 
	 * 功能描述:<截取正则匹配的字符串>
	 * @param text
	 * @param regExpression
	 * @param groupId
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static List<String> getStrsByRegular(String text, String regExpression, int groupId) {
		List<String> rets = new ArrayList<>();
		if (StringUtils.isEmpty(regExpression)) {
			return rets;
		}

		Pattern p = Pattern.compile(regExpression);
		Matcher m = p.matcher(text);
		while (m.find()) {
			rets.add(m.group(groupId));
		}

		return rets;
	}
	
	/**
	 * 
	 * 功能描述:<去掉空白元素>
	 * @param arrays
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static List<String> removeBlankElements(String [] arrays) {
		if (null == arrays) {
			return null; 
		}
		List<String> ss = new LinkedList<>();
		for (String e : arrays) {
			String s = e.replaceAll("[\\s]+", "");
			if (isNotEmpty(s)) {
				ss.add(e);
			}
		}
		return ss;
	}
	
	/**
	 * 
	 * 功能描述:<使用正则替换>
	 * @param src
	 * @param reg
	 * @param replacement
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static String replaceAll(String src, String reg,String replacement) {
		if (StringUtils.isEmpty(src) || StringUtils.isEmpty(reg)) {
			return src;
		} else {
			return src.replaceAll(reg, replacement);
		}
	}
	
	/**
	 * 
	 * 功能描述:<计算字符串的MD5>
	 * @param s
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws UnsupportedEncodingException 
	 * @author jlliu.Farrior
	 */
	@SuppressWarnings("restriction")
	public static String createMD5String(String s) throws NoSuchAlgorithmException, UnsupportedEncodingException {
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		BASE64Encoder base64en = new BASE64Encoder();
		return base64en.encode(md5.digest(s.getBytes("utf-8")));
	}	
	
		/**
	 * 
	 * 功能描述:<判断是否为纯数字>
	 * @param text
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static boolean isWholenumber(String text) {		
		return text.matches("[0-9]{1,}"); 
	}
	
		 /**
	 * 
	 * 功能描述:<检查字符串是否以数字开头>
	 * @param text
	 * @param regExpression
	 * @return 
	 * @author jcwang.Duke
	 */
	 public static boolean isStartWithNumber(String str) {
	    Pattern pattern = Pattern.compile("[0-9]*");
	    Matcher isNum = pattern.matcher(str.charAt(0)+"");
	    if (isNum.matches()) {
	        return true;
	    }
	    return false;
	 }
	
	
	/**
	 * 
	 * 功能描述:<计算字节数组MD5>
	 * @param bytes
	 * @return 
	 * @author jlliu.Farrior
	 */
	@SuppressWarnings("restriction")
	public static String createMD5String(byte [] bytes){
		if (null == bytes) {
			return "";
		}
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			LOGGER.error("字符串MD5计算异常：{}",ExceptionUtils.getFullStackTrace(e));
			return null;
		}
		// TODO: 替换编码方法
		// Base64
		BASE64Encoder base64en = new BASE64Encoder();
		return base64en.encode(md5.digest(bytes));
	}
	
	public static byte[] getBytes(String str,String charSet) {
		if (null == str) {
			return null;
		}
		byte[] bytes = null;
		try {
			bytes = str.getBytes(charSet);
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("字符串转换字节数组出现异常：{}",ExceptionUtils.getFullStackTrace(e));
		}		
		return bytes;
	}
	
	/**
	 * 
	 * 功能描述:<base64编码>
	 * @param bytes
	 * @return 
	 * @author jlliu.Farrior
	 */
	@SuppressWarnings("restriction")
	public static String encode4Base64(byte [] bytes) {
		if (null == bytes) {
			return "";
		}
		BASE64Encoder base64en = new BASE64Encoder();
		return base64en.encode(bytes);
	}
	
	public static byte[] decodeBase64(String base64) {
		byte[] bts = null;
		if (StringUtils.isEmpty(base64)) {
			return bts;
		}
		BASE64Decoder decoder = new BASE64Decoder();
		
		try {
			bts = decoder.decodeBuffer(base64);
		} catch (IOException e) {
			LOGGER.error("base64解码失败");
		}
		
		return bts;
	}
	
	
	/**
	 * 
	 * 功能描述:<是否包含中文字符>
	 * @param text
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static boolean isContainsChineseChar(String text) {
		
		if (isEmpty(text)) {
			return false;
		}
		Matcher m = PATTERN_CHINESE.matcher(text);
		if (m.find()) {
			return true;
		} else {
			return false;
		}
		
	}
	
	/**
	 * 
	 * 功能描述:<是否为英文字母>
	 * @param text
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static boolean isContainsEnglishChar(String text) {
		
		if (isEmpty(text)) {
			return false;
		}
		Matcher m = PATTERN_ENGLISH.matcher(text);
		if (m.find()) {
			return true;
		} else {
			return false;
		}
		
	}
	
	/**
	 * 
	 * 功能描述:<统计文本中英文和中文字符个数>
	 * @param text
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static int contentCharCounts(String text) {
		if (StringUtils.isEmpty(text)) {
			return 0;
		}
		char [] cs = text.toCharArray();
		int count = 0;
		for (char c : cs) {
			String s = String.valueOf(c);
			if ('a' <= c && c <='z' || 'A' <= c && c <='Z') {
				count++;
			} else if (isContainsChineseChar(s)) {
				count++;
			}
		}
		
		return count;
	}
	
	/**
	 * 例：
	 * ((中国)XXXX公司(香港办事处)) --> (中国)XXXX公司(香港办事处)
	 * (中国)XXXX公司(香港办事处)   --> (中国)XXXX公司(香港办事处)  
	 * 功能描述:<去掉首尾配对括号>
	 * @param text	文本
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static String trimBracketStart2End(String srcText) {
		if (StringUtils.isEmpty(srcText)) {
			return srcText;
		}
		// 统一括号字符
		String text = srcText.replace("（", "(");
		text = text.replace("）", ")");
		// 非括号开头的不考虑
		if (!(text.startsWith("(") || text.endsWith(")"))) {
			return srcText;
		}
		
		char [] cArrays = text.toCharArray();
		Stack<Character> stack = new Stack<Character>();
		int i=0;
		int length = cArrays.length;
		int eIndex = length - 1;
		
		boolean isMatch = true;
		boolean isEndMatch = true;
		for (char ch : cArrays) {
			i++;
			switch (ch) {
			case '(':
				// 首字符压入
				stack.push(ch);
				break;
			case ')':
				// 若无首字符进行匹配，则判断匹配失败
				if (stack.isEmpty()) {
					isMatch = false;
					break;
				} else {
					// 遇到尾字符，弹出上一个首字符
					stack.pop();
				}
				// 如果首字符提前弹出，则认为文本开头首字符和为字符不是一对
				if (stack.isEmpty() && i < eIndex) {
					isEndMatch = false;
				}
				break;
			default:
				break;
			}
			// 括号匹配失败了
			if (!isMatch) {
				break;
			}
		}
		// 从前之后 括号匹配无误：
		if (stack.isEmpty() && isMatch) {
			// 但是文本首尾括号是一对，则需要去掉首位括号
			if (isEndMatch) {
				srcText = srcText.substring(1,length);
				srcText = srcText.substring(0,length-2);
			}
		}
		
		return srcText;
	}
	
	/**
	 * 
	 * 功能描述:<首字符小写>
	 * @param s
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static String toLowerCaseFirstOne(String s){
		if(Character.isLowerCase(s.charAt(0))) {
			return s;
		} else {
			return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
		}
	}
	
	/**
	 * 取数字
	 * @param rule 
	 * @param str 
	 * @return sb.toString()
	 */
    public static List<String> getNumberByRuleEx(String rule, String str) {  
        List<String> retList = new ArrayList<String>();  
        Pattern p = Pattern.compile(rule);
        if (null != str && !str.isEmpty()){
	        Matcher m = p.matcher(str);        
	        
	        while (m.find())  {
		        for (int i = 0; i <= m.groupCount(); i++) {  
		        	retList.add(m.group());     
		        }  
	        }
        }
        return retList;  
    }
    
    
    /**
     * 金额量纲统一为：万
     * 若金额中不带“万” 需要除以10000：30000000 => 3000万
     * 功能描述:<格式化money>
     * @param fromMoney 传入金额
     * @return          格式化后的金额
     * @author jlliu.Farrior
     */
	public static String formatMoney(String fromMoney) {
		String numberStr = "";
		String unNumStr = "";
		Pattern numbericPattern = Pattern.compile("(\\d+(\\.\\d+)?)");
		Pattern unNumberPattern = Pattern.compile("[\\u4e00-\\u9fa5]+");
		if(!StringUtils.isBlank(fromMoney)){
			Matcher numberMatcher = numbericPattern.matcher(fromMoney);
			Matcher unNumMatcher = unNumberPattern.matcher(fromMoney);
			// 正则表达式查找金额
			if(numberMatcher.find()){
				numberStr = numberMatcher.group(1);
			}
			// 正则表达式查找中文
			if(unNumMatcher.find()){
				unNumStr = unNumMatcher.group(0);
			}
			//判断值中是否包含万这个字
			if (!unNumStr.contains("万") && StringUtils.isNotEmpty(numberStr)) {
				// 万元除以10000
				DecimalFormat df = new DecimalFormat("0.00");
				BigDecimal dbFromMoney = new BigDecimal(numberStr);
				BigDecimal dbToMoney = dbFromMoney.divide(new BigDecimal("10000"));
				numberStr = df.format(dbToMoney);
			}			
		}
		return numberStr;
	}
	
	
	
    
    /**
	 * 根据1970年到现在的秒数获得时间
	 * @param seconds
	 * @return
	 */
	public static String getDateBySeconds(String seconds){		
		if(isEmpty(seconds)) {
			return "";
		} else {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
			 return sdf.format(Long.parseLong(seconds));
		}
	}
	
	/**
	 * 
	 * 功能描述:<提取数字或者字母>
	 * @param str
	 * @return 
	 * @author 
	 */
	public static String extractNumbersOrLetter(String str){
		String regEx = "\\d+";
		Pattern pat = Pattern.compile(regEx);
		String regEx1 = "\\w+";
		Pattern pat1 = Pattern.compile(regEx1);
		if(str == null){
			return str;
		}
		Matcher matcher = pat.matcher(str);
		if(matcher.find()){
			str = matcher.group(0);
			str = Integer.toString((Integer.parseInt(str)));
		} else{
			Matcher matcher1 = pat1.matcher(str);
			if(matcher1.find()){
				str = matcher1.group(0);
			} else{
				str = "";
			}
		}		
		return str;
	}
	
	/**
	 * add by ljl for clean string on 20171215
	 * 清洗字符串
	 * @param s 输入参数
	 * @return  清洗后的字符串
	 */
	/**
	 * 
	 * 功能描述:<清洗网页字符串>
	 * @param s 输入参数
	 * @return 清洗后的字符串
	 * @author jlliu.Farrior
	 */
    public static String clean(String s){        
    	String ret = null;
    	if (StringUtils.isNotEmpty(s)) {
    		// 特殊字符
    		ret = s.replace("\u00A0", "").trim();
    		// 符号(：: ·)
    		ret = ret.replace("·", "").replace(":", "").replace("：", "");
    		// 网页符号：
    		ret = ret.replace("</br>", "").replace("<br />", "").replace("<p>", "").replace("\t", "").replace("&nbsp;", "").replace("&ldquo;", "")
    				 .replace("&rdquo;", "").replace("&hellip;", "").replace("</p>", "").replace("\n", "");
    	}
        return ret;
    }

	/**
	 * 
	 * 功能描述:<获取大型数字>
	 * 
	 * @param str
	 * @return
	 * @author jlliu.Farrior
	 */
	public static BigDecimal getBigdataByStr(String str) {
		BigDecimal ret = new BigDecimal(0);
		// 截取字符串中的数字：去掉资金单位
		String regex = "^(\\d+)(\\.\\d+)?";
		String numStr = "";
		if (StringUtils.isEmpty(str)) {
			return ret;
		}
		Pattern pattern = Pattern.compile(regex);// 正则匹配
		Matcher matcher = pattern.matcher(str);
		if (matcher.find()) {
			numStr = matcher.group(0);
		}
		if (StringUtils.isNotEmpty(numStr)) {
			ret = new BigDecimal(numStr);
		} else {
			ret = new BigDecimal(0);
		}
		return ret;
	}

	/**
	 * 获取资金中的单位 1000万人民币 截取 万人民币 功能描述:<获取资金中的单位>
	 * 
	 * @param str
	 * @return
	 * @author jlliu.Farrior
	 */
	public static String getUnitByStr(String str) {
		// 截取字符串资金单位
		String unit = "";
		String regex = "^(\\d+)(\\.\\d+)?";
		String numStr = "";
		if (StringUtils.isEmpty(str)) {
			return unit;
		}
		Pattern pattern = Pattern.compile(regex);// 正则匹配
		Matcher matcher = pattern.matcher(str);
		if (matcher.find()) {
			numStr = matcher.group(0);
		}
		return str.replace(numStr, "");
	}
    
	/**
	 * 取掉可能存在的中文符号，获取纯的中文字
	 * 功能描述:<去掉字符串中的中文符号>
	 * @param src
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static String cleanChineseSymbols(String src) {
		if (StringUtils.isEmpty(src)) {
			return src;
		}
		return src.replace("，|。|‘|’|“|”|（|）|！|、|；","");
	}
	
	/**
	 * 
	 * 功能描述:<获取字符串列表的所有字符集合>
	 * @param strs
	 * @return 
	 * @author jlliu.Farrior
	 */
	public static Set<String> getCharSet(String str){
		if (StringUtils.isEmpty(str)) {
			return null;
		}
		Set<String> set = new HashSet<>();
		char[] chars = str.toCharArray();
		for (char c : chars) {
			set.add(String.valueOf(c));
		}
		return set;
	}
	
	public static String replaceChars(String text, Map<String,String> map) {
		if (StringUtils.isEmpty(text) || MapUtils.isEmpty(map)) {
			return text;
		}
		StringBuffer sb = new StringBuffer();
		char [] chars = text.toCharArray();
		for (char c:chars) {
			String decode = MapUtils.getString(map, String.valueOf(c));
			if (StringUtils.isNotEmpty(decode)) {
				sb.append(decode);
			} else {
				sb.append(c);
			}
		}
		return sb.toString();
	}
	
	/**
	 * 功能描述:<字符串转换unicode>
	 * @param string
	 * @return 
	 * @author jlliu.Farrior
	 */
    public static String str2Unicode(String string) {
    	if (StringUtils.isEmpty(string)) {
    		return string;
    	}
        StringBuffer unicode = new StringBuffer();
        for (int i = 0; i < string.length(); i++) {
            char c = string.charAt(i);  // 取出每一个字符
            unicode.append("\\u" +Integer.toHexString(c));// 转换为unicode
        }
        return unicode.toString();
    }
	
    /**
     * 支持联系unicode字符  如： \u6025\u3524
     * 功能描述:<unicode编码转中文>
     * @param dataStr
     * @return 
     * @author jlliu.Farrior
     */
    public static String decodeUnicode(final String dataStr) {
        int start = 0;
        int end = 0;
        final StringBuffer buffer = new StringBuffer();
        while (start > -1) {
            end = dataStr.indexOf("\\u", start + 2);
            String charStr = "";
            if (end == -1) {
                charStr = dataStr.substring(start + 2, dataStr.length());
            } else {
                charStr = dataStr.substring(start + 2, end);
            }
            char letter = (char) Integer.parseInt(charStr, 16); // 16进制parse整形字符串。
            buffer.append(new Character(letter).toString());
            start = end;
        }
        return buffer.toString();
    }
	
	/**
	 * 
	 * 功能描述:校验数据是否符合正则
	 * @param value
	 * @param regex
	 * @return 
	 * @author jlren
	 */
	public static boolean regexStrValidate(String value, String regex){
	    if (StringUtils.isEmpty(value) || StringUtils.isEmpty(regex)) {
            return false;
        }
	    Pattern pattern = Pattern.compile(regex);
	    Matcher m = pattern.matcher(value);
	    if (m.find()) {
            return true;
        }
	    return false;
	}
	   /**
     * 
     * 功能描述:根据正则匹配数据
     * @param value
     * @param regex
     * @return 
     * @author jlren
     */
    public static String regexValueByRegex(String value, String regex){
        if (StringUtils.isEmpty(value) || StringUtils.isEmpty(regex)) {
            return null;
        }
        Pattern pattern = Pattern.compile(regex);
        Matcher m = pattern.matcher(value);
        if (m.find()) {
            return m.group();
        }
        return null;
    }
    
    /**
     * 注：无空格文本
     * 功能描述:<获取文本中所有的电话号码>
     * @param text
     * @return 
     * @author jlliu.Farrior
     */
    public static List<String> getAllTelphoneNums(String text) {
    	if (StringUtils.isEmpty(text)) {
    		return null;
    	}
    	Matcher m = PATTERN_TLENUMBERS.matcher(text);
    	List<String> teleNums = new LinkedList<>();
    	while(m.find()) {
    		teleNums.add(m.group(0));
    	}
    	return teleNums;
    }
}
